package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.common.constant.MqConst;
import com.atguigu.gmall.common.service.RabbitService;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentWay;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderInfoService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@SuppressWarnings("all")
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper ,OrderInfo> implements OrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${ware.url}")
    private String wareUrl;

    @Autowired
    private RabbitService rabbitService;


    /**
     * 提交订单
     * @param orderInfo
     * @return
     *order_info
     * order_detail
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long submitOrder(OrderInfo orderInfo) {
        //计算总金额
        orderInfo.sumTotalAmount();
        //订单状态
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        //支付方式
        orderInfo.setPaymentWay(PaymentWay.ONLINE.name());
        //交易号
        String outTradeNo = "ATGUIGU" + System.currentTimeMillis() + "" + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(outTradeNo);
        //订单描述
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        //拼接对象
        StringBuilder builder=new StringBuilder();

        for (OrderDetail orderDetail : orderDetailList) {
            builder.append(orderDetail.getSkuName()).append(",");

        }
        //判断长度
        if(builder.length()>50){

            orderInfo.setTradeBody(builder.toString().substring(0,50));
        }else {

            orderInfo.setTradeBody(builder.toString());
        }

        //操作时间
        orderInfo.setOperateTime(new Date());
        //失效时间
        Calendar calendar = Calendar.getInstance();
        //获取一天后
        calendar.add(Calendar.DATE,1);
        //设置
        orderInfo.setExpireTime(calendar.getTime());

        //进度状态
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());

        //保存订单
        orderInfoMapper.insert(orderInfo);

        //保存订单明细
        for (OrderDetail orderDetail : orderDetailList) {

            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);
        }

        //发送消息
        rabbitService.sendMessaged(
                MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,
                MqConst.ROUTING_ORDER_CANCEL,
                orderInfo.getId(),
                MqConst.DELAY_TIME
        );

        return orderInfo.getId();
    }

    /**
     * 生成流水号
     * @param userId
     * @return
     */
    @Override
    public String getTradeNo(String userId) {
        //生成流水号
        String tradeNo = UUID.randomUUID().toString().replaceAll("-", "");
        //存储到redis
        String tradeKey="user:"+userId+":tradeCode";
        redisTemplate.opsForValue().set(tradeKey,tradeNo,30, TimeUnit.MINUTES);

        //返回流水号
        return tradeNo;
    }

    /**
     * 校验流水号
     * @param userId
     * @param tradeNo
     * @return
     */
    @Override
    public boolean checkTradeNo(String userId, String tradeNo) {

        //设置流水号key
        String tradeKey="user:"+userId+":tradeCode";

        //获取redis中的流水号
        String tradeCode = (String) redisTemplate.opsForValue().get(tradeKey);


        return tradeNo.equals(tradeCode);
    }

    /**
     * 删除流水号
     * @param userId
     */
    @Override
    public void deleteTradeNo(String userId) {
        //设置流水号key
        String tradeKey="user:"+userId+":tradeCode";
        //删除流水号
        redisTemplate.delete(tradeKey);
    }

    /**
     *
     * 校验库存
     * @param skuId
     * @param skuNum
     * @return
     */
    @Override
    public boolean checkStock(Long skuId, Integer skuNum) {
        //编写请求路径
        String url=wareUrl+"/hasStock?skuId="+skuId+"&num="+skuNum;
        //发送请求
        String result = HttpClientUtil.doGet(url);
        //判断结果
        return "1".equals(result);
    }

    /**
     * 我的订单
     * @param orderInfoPage
     * @param userId
     * @return
     */
    @Override
    public IPage<OrderInfo> getOrderByUserId(Page<OrderInfo> orderInfoPage, String userId) {

        IPage<OrderInfo> infoIPage=orderInfoMapper.selectOrderByUserId(orderInfoPage,userId);
        //获取订单列表
        List<OrderInfo> records = infoIPage.getRecords();
        if(!CollectionUtils.isEmpty(records)){
            records.forEach(orderInfo -> {


                orderInfo.setOrderStatusName(OrderStatus.getStatusNameByStatus(orderInfo.getOrderStatus()));

            });


        }

        return infoIPage;
    }

    /**
     * 关闭超时订单
     * @param orderId
     */
    @Override
    public void execExpireOrder(Long orderId,String status) {


        //修改订单状态
        this.updateOrderStatus(orderId,ProcessStatus.CLOSED);

        //关闭支付信息

        if("2".equals(status)){
            rabbitService.sendMessaged(
                    MqConst.EXCHANGE_DIRECT_PAYMENT_CLOSE,
                    MqConst.ROUTING_PAYMENT_CLOSE,
                    orderId
            );

        }





    }

    /**
     * 修改订单状态
     * @param orderId
     * @param closed
     */
    @Override
    public void updateOrderStatus(Long orderId, ProcessStatus processStatus) {
        //封装修改对象
        OrderInfo orderInfo=new OrderInfo();
        //设置id
        orderInfo.setId(orderId);
        //设置订单状态
        orderInfo.setOrderStatus(processStatus.getOrderStatus().name());
        //设置流程状态
        orderInfo.setProcessStatus(processStatus.name());

        //修改订单状态
        orderInfoMapper.updateById(orderInfo);

    }

    /**
     *  发送消息到库存
     * @param orderId
     */
    @Override
    public void sendOrderStatus(Long orderId) {

        //1.准备数据
        String initWare=this.initWareOrderInfo(orderId);
        //修改订单状态
        this.updateOrderStatus(orderId,ProcessStatus.NOTIFIED_WARE);

        //2.发送消息
        rabbitService.sendMessaged(
                MqConst.EXCHANGE_DIRECT_WARE_STOCK,
                MqConst.ROUTING_WARE_STOCK,
                initWare
        );

    }

    /**
     * 转化数据
     * @param orderId
     * @return
     */
    private String initWareOrderInfo(Long orderId) {
        //获取订单数据
        OrderInfo orderInfo=this.getorderInfoById(orderId);
        return parsedOrderInfoStrin(orderInfo);
    }

    /**
     * 转化订单数据
     * @param orderInfo
     * @return
     */
    @Override
    public String parsedOrderInfoStrin(OrderInfo orderInfo) {
        //创建封装订单对象
        Map<String, Object> orderMap = getStringObjectMap(orderInfo);

        //转换json

        return JSONObject.toJSONString(orderMap);
    }

    /**
     * 订单类型转换
     * @param orderInfo
     * @return
     */
    @Override
    public Map<String, Object> getStringObjectMap(OrderInfo orderInfo) {
        Map<String,Object > orderMap=new HashMap<>();

        orderMap.put("orderId",orderInfo.getId());
        orderMap.put("consignee",orderInfo.getConsignee());
        orderMap.put("consigneeTel",orderInfo.getConsigneeTel());
        orderMap.put("orderComment",orderInfo.getOrderComment());
        orderMap.put("orderBody",orderInfo.getTradeBody());
        orderMap.put("deliveryAddress",orderInfo.getDeliveryAddress());
        orderMap.put("paymentWay",orderInfo.getPaymentWay().equals(PaymentWay.ONLINE.name()) ? "2" : "1");
        orderMap.put("wareId",orderInfo.getWareId());

        //获取订单明显集合
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();

        List<Map<String, Object>> deatilListMap = orderDetailList.stream().map(orderDetail -> {
            //创建封装对象
            Map<String, Object> detalMap = new HashMap<>();
            detalMap.put("skuId", orderDetail.getSkuId());
            detalMap.put("skuNum", orderDetail.getSkuNum());
            detalMap.put("skuName", orderDetail.getSkuName());

            return detalMap;

        }).collect(Collectors.toList());


        orderMap.put("details",deatilListMap);
        return orderMap;
    }

    /**
     * 拆单
     * @param orderId
     * @param wareSkuMap
     * @return
     */
    @Override
    public List<OrderInfo> orderSplit(String orderId, String wareSkuMap) {
        List<OrderInfo> infoList=new ArrayList<>();
        //转换拆单规则
        //[{"wareId":"1","skuIds":["2","10"]},{"wareId":"2","skuIds":["3"]}]
        List<Map> mapList = JSONArray.parseArray(wareSkuMap, Map.class);
        //查询原订单
        OrderInfo orderInfoOrigin = getorderInfoById(Long.parseLong(orderId));
        //遍历处理
        for (Map map : mapList) {
            //{"wareId":"1","skuIds":["2","10"]}
            //获取仓库id
            String wareId = (String) map.get("wareId");
            //获取skuIdS
            List<String> skuIds = (List<String>) map.get("skuIds");
            //创建订单
            OrderInfo subOrderInfo=new OrderInfo();
            //拷贝数据
            BeanUtils.copyProperties(orderInfoOrigin,subOrderInfo);
            //置空id
            subOrderInfo.setId(null);

            //设置仓库id
            subOrderInfo.setWareId(wareId);

            //创建子订单的商品明细
            List<OrderDetail> subOrderDetailList = new ArrayList<>();
            //获取原来的商品明细
            List<OrderDetail> orderDetailList = orderInfoOrigin.getOrderDetailList();

            //定义拼接订单描述对象
            StringBuilder builder=new StringBuilder();
            for (OrderDetail orderDetail : orderDetailList) {

                //遍历skuIds
                for (String skuId : skuIds) {

                    //对比id
                    if (skuId.equals(orderDetail.getSkuId().toString())) {

                        builder.append(orderDetail.getSkuName());
                        subOrderDetailList.add(orderDetail);

                    }

                }

            }

            //设置子订单明细
            subOrderInfo.setOrderDetailList(subOrderDetailList);


            //设置trade_body
            subOrderInfo.setTradeBody(builder.toString());

            //设置金额
            subOrderInfo.sumTotalAmount();

            //设置与父订单的关联
            subOrderInfo.setParentOrderId(orderInfoOrigin.getId());
            //保存到数据库
            submitOrder(subOrderInfo);


            //收集子订单

            infoList.add(subOrderInfo);
        }

        //设置父订单状态
        this.updateOrderStatus(orderInfoOrigin.getId(),ProcessStatus.SPLIT);


        return infoList;
    }


    /**
     * 获取订单信息
     * @param orderId
     * @return
     */
    private OrderInfo getorderInfoById(Long orderId) {

        //获取订单数据
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        //封装查询条件
        QueryWrapper<OrderDetail> queryWrapper=new QueryWrapper<>();
        queryWrapper.eq("order_id",orderId);

        //查询订单明细数据
        List<OrderDetail> orderDetailList = orderDetailMapper.selectList(queryWrapper);

        orderInfo.setOrderDetailList(orderDetailList);

        return orderInfo;
    }


}
